﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using System.Collections.Generic;
using HelixToolkit;
using System.Windows.Input;

namespace GraphicsDesigner
{

    /// <summary>
    /// Interaction logic for ucModel.xaml
    /// </summary>
    public partial class ucModel : UserControl
    {
        int size;
        List<Cube> listCubes = new List<Cube>();

        public ucModel()
        {
            DataContext = vm;
            Loaded += new RoutedEventHandler(ucModel_Loaded);
        }

        void ucModel_Loaded(object sender, RoutedEventArgs e)
        {
            view1.ZoomToFit(500);
            view1.Focus();
        }
        private void simpleButtonClick(object sender, RoutedEventArgs e)
        {
            // ClearViewport();

            //Triangle triangle = new Triangle();

            //size = Convert.ToInt32(txtSize.Text);

            //ModelVisual3D model = triangle.Draw(size,Colors.DarkBlue);

            //this.mainViewport.Children.Add(model);

            //HelixToolkit.CubeVisual3D cube = new HelixToolkit.CubeVisual3D();
            HelixToolkit.TruncatedConeVisual3D cube = new HelixToolkit.TruncatedConeVisual3D();
            HelixToolkit.PipeVisual3D tube = new HelixToolkit.PipeVisual3D();




            this.mainViewport.Children.Add(tube);

        }

        bool counter;
        private void cubeButtonClick(object sender, RoutedEventArgs e)
        {
            // DrawCube();
            Cube cube = new Cube();
            ModelVisual3D model;
            if (counter == true)
            {
                ClearViewport();
                model = cube.TestDraw(3, Colors.Chocolate, 0, 0, 0);
                this.mainViewport.Children.Add(model);

                HelixToolkit.XamlExporter xml = new HelixToolkit.XamlExporter("F:\\sto7oloTest.txt");
                xml.Export(model);
                xml.Close();
                counter = false;
            }
            else if (counter == false)
            {
                ClearViewport();
                model = cube.TestDraw(3, Colors.DeepPink, -1, -1, -1);
                this.mainViewport.Children.Add(model);
                counter = true;
            }
            listCubes.Add(cube);
            SetCamera();
        }

        private void ClearViewport()
        {
            ModelVisual3D m;
            for (int i = mainViewport.Children.Count - 1; i >= 0; i--)
            {
                m = (ModelVisual3D)mainViewport.Children[i];
                if (m.Content is DirectionalLight == false)
                    mainViewport.Children.Remove(m);
            }
        }


        #region Mouse Events

        private void mainViewport_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Point clickPoint = e.GetPosition(mainViewport);
            MessageBox.Show(clickPoint.ToString());
        }

        private void UserControl_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
        }

        #endregion

        #region Miriam

        private void SetCamera()
        {
            PerspectiveCamera camera = (PerspectiveCamera)mainViewport.Camera;
            Point3D position = new Point3D(
                Convert.ToDouble(cameraPositionXTextBox.Text),
                Convert.ToDouble(cameraPositionYTextBox.Text),
                Convert.ToDouble(cameraPositionZTextBox.Text)
            );
            Vector3D lookDirection = new Vector3D(
                Convert.ToDouble(lookAtXTextBox.Text),
                Convert.ToDouble(lookAtYTextBox.Text),
                Convert.ToDouble(lookAtZTextBox.Text)
            );
            camera.Position = position;
            camera.LookDirection = lookDirection;
        }

        private void btnClose_Click(object sender, RoutedEventArgs e)
        {
        }

        private void sliderX_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            DrawCube();
        }

        private void sliderY_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            DrawCube();
        }

        private void sliderZ_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            DrawCube();
        }

        private void DrawCube()
        {
            ClearViewport();

            Cube cube = new Cube();

            size = Convert.ToInt32(txtSize.Text);

            int x = Convert.ToInt32(sliderX.Value);
            int y = Convert.ToInt32(sliderY.Value);
            int z = Convert.ToInt32(sliderZ.Value);

            ModelVisual3D model = cube.Draw(size, Colors.DarkSeaGreen, x, y, z);

            this.mainViewport.Children.Add(model);
            SetCamera();
        }

        #endregion

        private void btnTestCube_Click(object sender, RoutedEventArgs e)
        {

        }

        private readonly MainViewModel vm = new MainViewModel();

        private void view1_MouseDown(object sender, MouseButtonEventArgs e)
        {
            //   Point clickPoint = e.GetPosition(this);
            // MessageBox.Show(clickPoint.ToString());
            bool shift = (Keyboard.IsKeyDown(Key.LeftShift));
            var p = e.GetPosition(view1);

            Vector3D n;
            var source = FindSource(p, out n);
            if (source != null)
            {
                if (shift)
                    vm.Remove(source);
                else
                    vm.Add(source, n);
            }
            else
            {
                var ray = Viewport3DHelper.Point2DtoRay3D(view1.Viewport, p);
                if (ray != null)
                {
                    var pi = ray.PlaneIntersection(new Point3D(0, 0, 0.5), new Vector3D(0, 0, 1));
                    if (pi.HasValue)
                    {
                        var pRound = new Point3D(Math.Round(pi.Value.X), Math.Round(pi.Value.Y), 0);
                        //    var pRound = new Point3D(Math.Floor(pi.Value.X), Math.Floor(pi.Value.Y), Math.Floor(pi.Value.Z));
                        //var pRound = new Point3D((int)pi.Value.X, (int)pi.Value.Y, (int)pi.Value.Z);
                        vm.AddVoxel(pRound);
                    }
                }
            }
            UpdatePreview();
        }

        Model3D FindSource(Point p, out Vector3D normal)
        {
            var hits = Viewport3DHelper.FindHits(view1.Viewport, p);

            foreach (var h in hits)
            {
                if (h.Model == vm.PreviewModel)
                    continue;
                normal = h.Normal;
                return h.Model;
            }
            normal = new Vector3D();
            return null;
        }

        void UpdatePreview()
        {
            var p = Mouse.GetPosition(view1);
            bool shift = (Keyboard.IsKeyDown(Key.LeftShift));
            Vector3D n;
            var source = FindSource(p, out n);
            if (shift)
            {
                vm.PreviewVoxel(null);
                vm.HighlightVoxel(source);
            }
            else
            {
                vm.PreviewVoxel(source, n);
                vm.HighlightVoxel(null);
            }

        }

        private void view1_MouseMove(object sender, MouseEventArgs e)
        {
            UpdatePreview();
        }
    }
}
